"""
文案类
"""
from PIL import Image
import cv2 as cv
import numpy as np
import textwrap

class TextEngine:
    """
    文字引擎
    """
    def __init__(self, text: str, line_width: int, font_size: int):
        """
        文字引擎初始化
        :param text: 要插入的文字
        :param line_width: 行宽
        :param font_size: 文字大小
        """
        self.text = text
        self.line_width = line_width
        self.font_size = font_size
        self.line_size = int(line_width / font_size)
        self.all_line = []
        first_line = self.text[:self.line_size - 2]
        other_line = self.text[len(first_line) - 1:]
        other_lines = textwrap.wrap(other_line, self.line_size)
        self.all_line.append(first_line)
        for line in other_lines:
            self.all_line.append(line)

    def is_punctuation(self, font: str):
        """
        判断是不是标点符号
        :param font: 单个文字
        :return: 是否是标点符号，True: 是标点符号;False: 不是标点符号
        """
        punctuation_str = ",，.。!！\''‘；;?？\"”、0123456789abcdefghigklmnopqrstuvwxyzABCDEFGHIGKLMNOPQRSTUVWXYZ"
        if font in punctuation_str:
            return True
        else:
            return False

    def calculate_punctuation(self, line_length: int, font_index: int):
        """
        计算第n行标点符号的个数
        :param line_length: 第n行
        :param font_index: 字符下标
        :return 额外的边距
        """
        line = self.all_line[line_length]
        # 统计标点个数
        punctuation_size = 0
        first_index = -1
        for index in range(len(line)):
            font = line[index]
            # 遍历每个字
            if self.is_punctuation(font) is True:
                # 标点符号 + 1
                punctuation_size = punctuation_size + 1
                first_index = index
        if font_index > first_index:
            return int(punctuation_size * (self.font_size / 2) / (len(line) - first_index))
        return 0

class Text:
    """
    文案
    """

    def __init__(self, text: str, top: int, margin: int, font_color=(0, 255, 0), font_size=30):
        """
        初始化函数
        :param text: 文本
        :param top 距离顶部多少px
        :param margin: 左右边距
        :param font_color: 文本颜色
        :param font_size: 文本大小
        """
        self.text: str = text
        self.top: int = top
        self.margin: int = margin
        self.font_color: () = font_color
        self.font_size: int = font_size


class Img:
    """
    图片
    """

    def __init__(self, path: str, top: int, margin: int):
        """
        初始化图片类
        :param path: 路径
        :param top: 上边距
        :param margin: 边距
        """
        self.multiple: int = 0
        self.path: str = path
        self.margin: int = margin
        self.top: int = top
        self.shrink: int = 0

        self.original_img: Image.Image = Image.open(self.path)
        self.shrink_img: Image.Image = self.original_img.copy()
        self.width: int = self.original_img.width
        self.height: int = self.original_img.height

    def zoom_original(self, zoom: int):
        """
        对原图进行缩放
        :param zoom: 缩放百分比，大于0：放大,小于0：缩小
        """
        scaling_width = self.width
        scaling_height = self.height
        if zoom > 0:
            # 放大
            true_scaling = 1 + (zoom / 100)
            scaling_width = int(self.width * true_scaling)
            scaling_height = int(self.height * true_scaling)

        elif zoom < 0:
            # 缩小
            zoom = -zoom
            true_scaling = 1 + (zoom / 100)
            scaling_width = int(self.width / true_scaling)
            scaling_height = int(self.height / true_scaling)

        self.original_img = self.original_img.resize((scaling_width, scaling_width))
        self.width = scaling_width
        self.height = scaling_height

    def show(self, win_name: str, shrink: int):
        """
        显示插入的图片
        :param win_name: 窗口名称
        :param shrink: 缩小的倍数
        """
        self.shrink = shrink
        self.shrink_img = self.original_img.resize((int(self.width / self.shrink), int(self.height / self.shrink)))
        img = cv.cvtColor(np.asarray(self.shrink_img), cv.COLOR_RGB2BGR)
        cv.imshow(win_name, img)
        cv.waitKey()
        cv.destroyAllWindows()

    def center_cropping(self, width: int, height: int):
        """
        居中裁剪图片
        :param width: 裁剪过后的宽度
        :param height: 裁剪过后的高度
        :return: 裁剪过后的图片
        """
        # 判断裁剪的尺寸是否大于图片本身
        diff_width = width - self.width
        diff_height = height - self.height
        zoom = 0
        if diff_width > 0 or diff_height > 0:
            # 想要的尺寸过大
            if diff_width >= diff_height:
                # 过宽
                zoom = width / self.width
            else:
                # 过长
                zoom = height / self.height
        self.zoom_original(int(zoom * 100))
        #
        # 计算裁剪框的左上角坐标
        left = (self.width - width) // 2
        top = (self.height - height) // 2

        # 计算裁剪框的右下角坐标
        right = (self.width + width) // 2
        bottom = (self.height + height) // 2
        self.original_img = self.original_img.crop((left, top, right, bottom))
        self.width = width
        self.height = height
        return self.original_img
